package com.example.badmintonUser.Gym.GymServerImpl;

import com.example.badmintonCommon.DTO.BookPlaceRequest;
import com.example.badmintonCommon.entity.Gym;
import com.example.badmintonCommon.entity.Order;
import com.example.badmintonCommon.pojo.Result;
import com.example.badmintonDB.GymDBserver;
import com.example.badmintonUser.Gym.GymServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class GymServerImpl implements GymServer {

    private final GymDBserver gymDBserver;
    @Autowired
    public GymServerImpl(GymDBserver gymDBserver){
        this.gymDBserver=gymDBserver;
    }

    //用户查看某场地信息
    @Override
    public Result<String> FindGymMes(Integer id){
        Gym gym = gymDBserver.FindGymMes(id);
        if(gym ==null){
            return Result.success("未存在该场地");
        }
        else return Result.success(gym.toString());
    }

    //用户查看所有场地信息
    @Override
    public Result<List<Gym>> FindAllGyms(){
        return Result.success(gymDBserver.FindAllGyms());
    }

   //用户预定场地
   @Override
   public synchronized Result<String> bookPlace(BookPlaceRequest bookPlaceRequest) {


       try {
           // 1. 根据场地ID获取场地信息
           Gym gym = gymDBserver.FindGymMes(bookPlaceRequest.getId());
           if (gym == null) {
               return Result.error("场地不存在");
           }

           int[][] places = gym.getPlace();
           List<Integer> times = bookPlaceRequest.getTimes();
           String tel = bookPlaceRequest.getTel();

           // 2. 验证时间段是否可用
               String validationResult = validateTimeSlots(places, times);
               if (!validationResult.equals("OK")) {
                   return Result.error(validationResult);
               }


           // 3. 生成订单ID
           String oderId = generateOrderId();

           // 4. 构建时间段字符串和更新场地状态
           Map<String, String> bookingResult = processBooking(places, times);
           String playTime = bookingResult.get("playTime");

           // 5. 从时间索引中提取预定日期
           String playDay = extractPlayDayFromTimes(times);
           System.out.println(playDay);
           // 6. 创建订单记录（传入正确的预定日期）
           Order oder = createOrder(oderId, tel, bookPlaceRequest.getId(), playTime, playDay);
           gymDBserver.CreateOder(oder);

           // 7. 更新场地预定状态
           gymDBserver.UpdateGymPlace(bookPlaceRequest.getId(), places);

           return Result.success("预定成功，订单号: " + oderId + "，预定日期: " + playDay);

       } catch (Exception e) {
           e.printStackTrace();
           return Result.error("预定失败: " + e.getMessage());
       }
   }

    /**
     * 创建订单对象（添加playDay参数）
     */
    private Order createOrder(String oderId, String tel, Integer gymId, String playTime, String playDay) {
        Order oder = new Order();
        oder.setOderId(oderId);
        oder.setTel(tel);
        oder.setOderPlace(gymId);
        oder.setPlayTime(playTime);
        oder.setPlayDay(playDay); // 使用计算出的预定日期
        oder.setOderTime(new Date());
        oder.setOderStatus("进行中");
        return oder;
    }

    /**
     * 从时间索引中提取预定日期
     */
    private String extractPlayDayFromTimes(List<Integer> times) {
        if (times == null || times.isEmpty()) {
            return LocalDate.now().toString(); // 默认返回今天
        }

        // 提取所有不同的日期
        return times.stream()
                .map(timeIndex -> timeIndex / 24) // 获取天数索引
                .distinct() // 去重
                .map(dayIndex -> LocalDate.now().plusDays(dayIndex).toString()) // 转换为日期字符串
                .sorted() // 按日期排序
                .collect(Collectors.joining(",")); // 用逗号连接
    }

    private String validateTimeSlots(int[][] places, List<Integer> times) {
        for (Integer timeIndex : times) {
            int dayIndex = timeIndex / 24;
            int hourIndex = timeIndex % 24;

            // 检查索引范围
            if (dayIndex < 0 || dayIndex >= 7 || hourIndex < 0 || hourIndex >= 24) {
                return "时间段超出范围";
            }

            // 检查是否已被预定
            if (places[dayIndex][hourIndex] == 1) {
                return "时间段 " + getTimeSlotDescription(dayIndex, hourIndex) + " 已被预定";
            }
        }
        return "OK";
    }

    /**
     * 生成订单ID
     */
    private String generateOrderId() {
        String timePart = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
        int randomPart = (int) ((Math.random() * 9 + 1) * 100);
        return timePart + randomPart;
    }

    /**
     * 处理预定逻辑
     */
    private Map<String, String> processBooking(int[][] places, List<Integer> times) {
        Map<String, String> result = new HashMap<>();
        StringBuilder playTime = new StringBuilder();

        for (Integer timeIndex : times) {
            int dayIndex = timeIndex / 24;
            int hourIndex = timeIndex % 24;

            // 标记为已预定
            places[dayIndex][hourIndex] = 1;

            // 构建时间段字符串
            playTime.append(hourIndex)
                    .append(":00 - ")
                    .append(hourIndex + 1)
                    .append(":00   ");
        }

        result.put("playTime", playTime.toString());
        return result;
    }

    /**
     * 获取时间段描述
     */
    private String getTimeSlotDescription(int dayIndex, int hourIndex) {
        LocalDate date = LocalDate.now().plusDays(dayIndex);
        return date.toString() + " " + hourIndex + ":00-" + (hourIndex + 1) + ":00";
    }



    //用户取消预定场地
    @Override
    public Result<String> UnbookPlace(String orderId, BookPlaceRequest bookPlaceRequest) {
        try {
            // 1. 查找订单
            Order order = gymDBserver.FindOrderById(orderId);
            if (order == null) {
                return Result.error("订单不存在");
            }
            if ("已取消".equals(order.getOderStatus())) {
                return Result.error("该订单已取消");
            }

            // 2. 获取场地信息
            Gym gym = gymDBserver.FindGymMes(bookPlaceRequest.getId());
            if (gym == null) {
                return Result.error("场地不存在");
            }

            int[][] places = gym.getPlace();
            List<Integer> times = bookPlaceRequest.getTimes();

            // 3. 恢复被占用的时间段（将 1 改回 0）
            for (Integer timeIndex : times) {
                int dayIndex = timeIndex / 24;
                int hourIndex = timeIndex % 24;

                // 索引检查
                if (dayIndex < 0 || dayIndex >= places.length || hourIndex < 0 || hourIndex >= places[dayIndex].length) {
                    return Result.error("时间索引超出范围: " + timeIndex);
                }

                // 恢复场地状态
                places[dayIndex][hourIndex] = 0;
            }

            // 4. 更新订单状态与数据库
            gymDBserver.CancelOder(orderId, "已取消");
            gymDBserver.UpdateGymPlace(bookPlaceRequest.getId(), places);

            return Result.success("订单已成功取消");

        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("取消失败: " + e.getMessage());
        }
    }



}
